package piis;

import Algorithms.LinearRegression;
import Algorithms.SimulatedAnnealing;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JFrame;
import org.jfree.ui.RefineryUtilities;

/**
 *
 * @author Atuan
 */
public class Test6 {
    
    private static String path = "src/test6";
    private static double globalMin;
    private static double globalMax;
    private static List<TestData> data;
    private static int scaleFactor = 1;
    private static int degree = 2;
    
    public static void readMultiLRData(String filename){
        BufferedReader br = null;        
        try {
            String line="";
            br = new BufferedReader(new FileReader(path+"/"+filename));
            globalMin = Double.parseDouble(br.readLine());
            globalMax = Double.parseDouble(br.readLine());
            data = new ArrayList<>();
            Boolean readStill = true;
            Boolean skipOne = false;
            while (readStill) {
                if(!skipOne){
                    line = br.readLine();
                    if(line == null){
                        break;
                    }
                }
                String[] lineArray = line.split(" ");                
                if(lineArray[0].equals("TRAIN")){
                    skipOne = false;
                    TestData d = new TestData();
                    d.setAction("TRAIN");
                    d.setMin(Double.parseDouble(lineArray[1]));
                    d.setMax(Double.parseDouble(lineArray[2]));
                    Boolean isData = true;
                    List<Double> tX = new ArrayList<>();
                    List<Double> tempY = new ArrayList<>();
                    int counter = 0;
                    while(isData){
                        line = br.readLine();
                        String[] lineArr = line.split(" "); 
                        if(lineArr.length == 2){
                            tX.add((Double.parseDouble(lineArr[0])/scaleFactor));
                            tempY.add(Double.parseDouble(lineArr[1])/scaleFactor);
                            counter++;
                        } else {
                            isData = false;
                            skipOne = true;
                        }
                    }
                    double[][] tempX = new double[degree][counter];
                    for(int i=1; i <= degree ; i++){
                        for(int j=0;j<tX.size(); j++){
                            tempX[i-1][j] = Math.pow(tX.get(j) /scaleFactor, i);
                        }
                    }
                    d.setX(tempX);
                    d.setY(tempY);
                    data.add(d);
                } else if(lineArray[0].equals("MIN") || lineArray[0].equals("MAX")){
                    skipOne = false;
                    TestData d = new TestData();
                    d.setAction(lineArray[0]);
                    d.setMin(Double.parseDouble(lineArray[1]));
                    d.setMax(Double.parseDouble(lineArray[2]));
                    String l = br.readLine();
                    d.setValue(Double.parseDouble(l));
                    data.add(d);                    
                } else {
                    skipOne = false;
                    TestData d = new TestData();
                    d.setAction(lineArray[0]);
                    d.setMin(Double.parseDouble(lineArray[1]));
                    d.setMax(Double.parseDouble(lineArray[2]));
                    data.add(d);
                } 
            }
        } catch (IOException e) {
        } finally {
            try {
                if (br != null){
                    br.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
//        for(TestData d : data){
//            System.out.println(d.toString());
//        }
    }
    
    
    public static void main(String[] args) {
        File dir = new File(path);
        String[] files = dir.list();
        
        if (files == null){
            System.out.println("Empty directory");
        } else { 
            for (int i=0;i<files.length;i++){
                if(files[i].endsWith(".in")){
                    int iterations = 1000000;
                    if(files[i].equals("1.in")){
                        degree = 2;
                        iterations = 2000000;
                        continue;
                    } else if(files[i].equals("2.in")){
                        degree = 4;
                        iterations = 500000;
                        continue;
                    } else if(files[i].equals("3.in")){
                        degree = 4;
                        iterations = 800000;
//                        continue;
                    }
                    
                    readMultiLRData(files[i]);
                    LinearRegression lr = new LinearRegression(degree+1);
                    lr.simulatedAnnealing(iterations, globalMin, globalMax, data);
                    // Create a plot.
                    
                    Map<Double,Double> map = new HashMap<>();
                    try{
	                FileWriter paramsF = new FileWriter(path + "/" + files[i].replace(".in", "") + "_result4.out");
	                             
                        for(double p = globalMin; p <= globalMax; p += 0.1){
                            double yy = lr.func(p/scaleFactor)*scaleFactor;
                            map.put(p, yy);
                            paramsF.write(p + " " + yy + "\r\n");
                        }
	                
                        paramsF.close();

                    }catch(Exception e){
                            e.printStackTrace();
                    }
                    
                    Plot demo = new Plot("Assignment 3", "ASSIGNMENT" + ": Grade = " + degree ,map);
                    demo.pack();
                    RefineryUtilities.centerFrameOnScreen(demo);
                    demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    demo.setVisible(true);
                }
            }
        }
    }
}
